#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <list>
#include <pthread.h>
using namespace std;

void *getuserinput(void *threadid);
void *sendrequest(void *threadid);

pthread_mutex_t lock;
pthread_mutex_t mymutex;
pthread_cond_t count_cv;
list<char *> sentencelist;
int ended = 0;
char *serverip;
char *port;

int main(int argc, char *argv[]){
	if(argc!=3) {
		return 0;
	}
	
	serverip = argv[1];
	port = argv[2];
    pthread_attr_t attr;
    pthread_mutex_init(&lock, NULL);
    pthread_mutex_init(&mymutex,NULL);
    pthread_cond_init(&count_cv,NULL);
    
    pthread_t threads[2];
    
    pthread_create(&threads[1], NULL, sendrequest, (void *)1);
    pthread_create(&threads[0], NULL, getuserinput,(void *)0);
    pthread_join(threads[0],NULL);
    pthread_join(threads[1],NULL);
                  
    pthread_mutex_destroy(&lock);
    pthread_mutex_destroy(&mymutex);
    pthread_exit(NULL);
    return 0;
}

void *getuserinput(void *threadid) {
  
    string sentence;
    char mybuffer[1024];
    
    while(ended == 0) {
        
        fgets(mybuffer, 1024, stdin);
        cout << "cin" << mybuffer << endl;
        pthread_mutex_lock(&lock);
        sentencelist.push_back(mybuffer);
        pthread_mutex_unlock(&lock);
        
        pthread_cond_signal(&count_cv);
    }  
    pthread_exit(NULL);
}

void *sendrequest(void * threadid) {
        
        pthread_mutex_lock(&mymutex);

		int sid = socket(AF_INET,SOCK_STREAM,0);
		if(sid == -1) {
			cout << "error in initializing socket" << endl;
			ended=1;
			pthread_exit(NULL);
		}

		struct sockaddr_in server;
		server.sin_family = AF_INET;
		server.sin_addr.s_addr = inet_addr(serverip);
		server.sin_port = htons(atoi(port));

		if(connect(sid,(struct sockaddr *)&server,sizeof(server))== -1) {
			//if((err = errno) != EINPROGRESS){
	            cout << "Error connecting socket" << endl;
				ended=1;
	            pthread_exit(NULL);
	        //}
	    }
        
		while(ended == 0) {
            char *buffer;
            int bytecount;
            int buffer_len=0;
			
            if(sentencelist.empty()) {
                pthread_cond_wait(&count_cv,&mymutex);
            }
                pthread_mutex_lock(&lock);
        
                buffer=sentencelist.front();
                sentencelist.pop_front();
            cout << "cin" << buffer << endl;

                pthread_mutex_unlock(&lock);
				
                //buffer[sizeof(buffer)+1]='\0';
                if(send(sid,buffer,sizeof(buffer),0) == -1) {
                    cout << "error in sending" << endl;
                    ended=1;
                    break;
                }

                if(recv(sid, buffer,sizeof(buffer),0) == -1) {
                    cout << "error in receiving" << endl;
                    ended=1;
                    break;
                }

                cout << "Server: " << buffer << endl;
                sleep(2);
                pthread_mutex_unlock(&mymutex);
			
		}
		close(sid);
		pthread_exit(NULL);
	}
 
	    

